#define PACK_GLOBAL
#include "pack.h"

#include "../libSDL/include/SDL_thread.h"
//static int ptrxx[3];

void rep_init(void)
{
  rep_a.mutex = SDL_CreateMutex();
  rep_a.cond = SDL_CreateCond();
  rep_a.id_g = rep_a.id_p = 0;
  rep_a.size = BUF_NO;
  rep_v.mutex = SDL_CreateMutex();
  rep_v.cond = SDL_CreateCond();
  rep_v.id_g = rep_v.id_p = 0;
  rep_v.size = BUF_NO;
  {
  	int i;
	printf ("video:\n");
  	for (i = 0; i < BUF_NO; i ++) {
		printf ("%d: 0x%x\n", i, (int)&rep_v.buf[i][0]);
  	}
	printf ("audio:\n");
  	for (i = 0; i < BUF_NO; i ++) {
		printf ("%d: 0x%x\n", i, (int)&rep_a.buf[i][0]);
  	}
  }
//printf ("&ptrxx: 0x%x\n", (int)ptrxx);
}
void pack_init(pack *pa)
{
//printf ("&pack: 0x%x\n", (int)pa);
  pa->mutex = SDL_CreateMutex();
  pa->cond = SDL_CreateCond();
  pa->id_g = pa->id_p = 0;
  pa->size = PACKET_NO;
}

int repa_get(AVPacket * pkt, int size)
{
  if (size > AUD_BUF_SZ) {
    printf ("audio pack size 0x%x over limit\n", size);
    return -1;
  }
  SDL_LockMutex(rep_a.mutex);
  for(;;) {
    if (rep_a.size) {
      rep_a.size --;

      av_init_packet(pkt);
      pkt->data = &(rep_a.buf[rep_a.id_g][0]);
      pkt->size = size;
      pkt->destruct = (void *)1;

//printf ("alloc audio %d: 0x%x\n", rep_a.id_g, (int)pkt->data);
      if (++ rep_a.id_g == BUF_NO)
        rep_a.id_g = 0;
// for checking later
memset ((char *)((uint32_t)pkt->data + size), 0, AUD_BUF_SZ - size);
      break;
    } else {
      SDL_CondWait(rep_a.cond, rep_a.mutex);
    }
  }
  SDL_UnlockMutex(rep_a.mutex);
  return 0;
}

void repa_put(AVPacket *pkt)
{
  SDL_LockMutex(rep_a.mutex);
  rep_a.size ++;
  pkt->destruct = NULL;
//printf ("free audio %d:\n", rep_a.id_p);
  if (++ rep_a.id_p == BUF_NO)
    rep_a.id_p = 0;
//checking
{
  int i;
  char *ptr = (char *)((uint32_t)pkt->data + pkt->size);
  for (i = AUD_BUF_SZ - pkt->size; i != 0; i --) {
    if (*ptr != 0) {
      printf("error in repa_put, while(1)\n");
      while (1);
    }
    ptr ++;
  }
}
  SDL_CondSignal(rep_a.cond);
  SDL_UnlockMutex(rep_a.mutex);
}
int repv_get(AVPacket * pkt, int size)
{
  if (size > VID_BUF_SZ) {
    printf ("video pack size 0x%x over limit\n", size);
    return -1;
  }
  SDL_LockMutex(rep_v.mutex);
  for(;;) {
    if (rep_v.size) {
      rep_v.size --;

      av_init_packet(pkt);
      pkt->data = &(rep_v.buf[rep_v.id_g][0]);
      pkt->size = size;
      pkt->destruct = (void *)1;

//printf ("alloc video %d: 0x%x\n", rep_v.id_g, (int)pkt->data);
      if (++ rep_v.id_g == BUF_NO)
        rep_v.id_g = 0;
// for checking later
memset ((char *)((uint32_t)pkt->data + size), 0, VID_BUF_SZ - size);
      break;
    } else {
      SDL_CondWait(rep_v.cond, rep_v.mutex);
    }
  }
  SDL_UnlockMutex(rep_v.mutex);
  return 0;
}

void repv_put(AVPacket * pkt)
{
  SDL_LockMutex(rep_v.mutex);
  pkt->destruct = NULL;
  rep_v.size ++;
//printf ("free video %d:\n", rep_v.id_p);
  if (++ rep_v.id_p == BUF_NO)
    rep_v.id_p = 0;
//checking
{
  int i;
  char *ptr = (char *)((uint32_t)pkt->data + pkt->size);
  for (i = VID_BUF_SZ - pkt->size; i != 0; i --) {
    if (*ptr != 0) {
      printf("error in repv_put, while(1)\n");
      while (1);
    }
    ptr ++;
  }
}
  SDL_CondSignal(rep_v.cond);
  SDL_UnlockMutex(rep_v.mutex);
}

int rep_get(AVPacket * pkt, int size)
{
  pkt->data = buf_other;
  pkt->size = size;
  return 0;
}

AVPacketList * pack_get(pack * pa)
{
  AVPacketList * ptr;
  SDL_LockMutex(pa->mutex);
  for(;;) {
    if (pa->size) {
      pa->size --;
      ptr = &(pa->pktl[pa->id_g]);

//printf ("alloc pack %d 0x%x\n", pa->id_g, (int)ptr);
      if (++ pa->id_g == PACKET_NO)
        pa->id_g = 0;
      break;
    } else {
      SDL_CondWait(pa->cond, pa->mutex);
    }
  }
  SDL_UnlockMutex(pa->mutex);
  return ptr;
}

void pack_put(pack * pa)
{
  SDL_LockMutex(pa->mutex);
  pa->size ++;
//printf ("free pack %d 0x%x\n", pa->id_p, (int)&(pa->pktl[pa->id_p]));
  if (++ pa->id_p == PACKET_NO)
    pa->id_p = 0;
  SDL_CondSignal(pa->cond);
  SDL_UnlockMutex(pa->mutex);
}

